package cn.yuanqiao.es.service.impl;

import cn.yuanqiao.common.constant.Constants;
import cn.yuanqiao.common.core.domain.entity.SysRole;
import cn.yuanqiao.common.utils.PageUtils;
import cn.yuanqiao.common.utils.SecurityUtils;
import cn.yuanqiao.es.domain.QueryFile;
import cn.yuanqiao.es.mapper.ElasticsearchApiMapper;
import cn.yuanqiao.es.service.ElasticsearchApiService;
import cn.yuanqiao.es.service.FileListService;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ProjectName: ruoyi-modules-system
 * @Package: cn.yuanqiao.es.service.impl
 * @ClassName: FileListServiceImpl
 * @Author: lenovo
 * @Description: hbWang
 * @Date: 2023/6/29 16:57
 * @Version: 1.0
 */
@Service
public class FileListServiceImpl implements FileListService {

    @Autowired
    ElasticsearchApiMapper elasticsearchApiMapper;

    @Autowired
    ElasticsearchApiService elasticsearchApiService;

    @Override
    public List<Map<String, Object>> queryFileList(QueryFile queryFile) {
        //获取当前登录用户信息
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sqlFile = new StringBuilder("");
        sqlFile.append(" IS_DEL = 0 AND STATE = '5' ");
        String tableName = "";
        if (queryFile != null && StringUtils.isNotBlank(queryFile.getGroupId())) {
            //查询档案门类
            Map<String, Object> fileMap = elasticsearchApiMapper.selectTableData(tenantCode +
                    Constants.BIG_TABLE_NAME, " FILE_TABLE_NAME ", " ID= " + queryFile.getCategoryId()).get(0);
            tableName = fileMap.get("FILE_TABLE_NAME").toString();
        } else {
            List<Map<String, Object>> mapList = queryCategoryIds(null, queryFile.getMenuId(),"");
            if (ObjectUtils.isEmpty(mapList)) {
                return new ArrayList<>();
            }
            tableName = mapList.stream().map(m -> String.valueOf(m.get("FILE_TABLE_NAME"))).collect(Collectors.joining("','"));
        }
        sqlFile.append(" and SUB_TABLE_NAME in ('" + tableName + "') ");
        if (StringUtils.isNotBlank(queryFile.getQzh()) && !"-1".equals(queryFile.getQzh())) {
            sqlFile.append(" and QZH in ('" + queryFile.getQzh() + "') ");
        }
        //拼接查询条件
        sqlFile.append(concatQueryCondition(queryFile, queryFile.getFileField()));
        if (!StringUtils.isEmpty(queryFile.getOrder())) {
            sqlFile.append(" order by "+queryFile.getOrder());
        }
        //分页
        PageUtils.startPage();
        //组件  IS_EFILE,IS_ENTITY
        List<Map<String, Object>> dataListFile = elasticsearchApiMapper.selectTableData(tenantCode +
                Constants.BIG_TABLE_YQDA, queryFile.getFileField() + " ,DA_ID, SUB_TABLE_NAME  ", sqlFile.toString());
        return dataListFile;
    }

    @Override
    public List<Map<String, Object>> categoryList(String menuId,String qzh) {
        //查询档案门类
        List<Map<String, Object>> categoryList = queryCategoryIds(null, menuId,qzh);
        return categoryList;
    }


    /**
     * 查询展示字段信息
     *
     * @param json
     * @return
     */
    @Override
    public List<Map<String, String>> queryFields(JSONObject json) {
        //获取当前登录用户信息SecurityUtils.getTenantCode()
        String categoryId = json.getString("categoryId"); //门类id
        String menuId = json.getString("menuId"); //菜单id
        String groupId = json.getString("groupId");//门类id
        String type = json.getString("type");//门类id
        String qzh = json.getString("qzh");//门类id
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sql = new StringBuilder("");
        String ordering = "";
        if (StringUtils.isNotBlank(groupId)) {
            sql.append(" and tn.GROUP_ID = '" + groupId + "' ");
            List<Map<String, Object>> dataList = elasticsearchApiMapper.selectTableData(tenantCode +
                    Constants.TABLE_YQ_APP, " ID,JIANQUERY,JIANLISTFIELD ", " MENU_ID = '" + menuId + "' "
                    + " and CATEGORY_ID = '" + categoryId + "' ");
            if (dataList != null && dataList.size() > 0) {
                ordering = dataList.get(0).get("JIANLISTFIELD") == null ? "" : dataList.get(0).get("JIANLISTFIELD").toString();
                if (StringUtils.isNotBlank(ordering)) {
                    sql.append(" and tn.FIELD_NAME in  ('" + ordering.replace(",", "','") + "') ");
                } else {
                    sql.append(" AND tn.IS_HIDDEN = 0  and tn.IS_SYSTEM = 1 ");
                }
            }
        } else {
            List<Map<String, Object>> mapList = queryCategoryIds(null, menuId,qzh);
            if (ObjectUtils.isEmpty(mapList)) {
                return null;
            }
            String groupIds = mapList.stream().map(m -> String.valueOf(m.get("GROUP_ID"))).collect(Collectors.joining(","));
            sql.append(" and tn.GROUP_ID in (" + groupIds + ") ");
            sql.append(" AND tn.IS_HIDDEN = 0  and tn.IS_SYSTEM = 1 ");
        }
        sql.append(" and tn.TYPE = 0  ");
        //查询元数据方案信息
        List<Map<String, Object>> dataList = elasticsearchApiMapper.selectMDataListTableData
                (tenantCode + Constants.BIG_TABLE_M_DATA_LIST,
                        sql.toString());
        List<Map<String, String>> tabulationData = dataList.stream().collect(Collectors.groupingBy(c -> c.get("FIELD_NAME"))).values().stream().map(a ->
        {
            Map<String, String> mm = new HashMap<>();
            mm.put("FIELD_NAME", String.valueOf(a.get(0).get("FIELD_NAME")));
            mm.put("FIELD_CAPTION", a.stream().map(dd -> String.valueOf(dd.get("FIELD_CAPTION"))).distinct().collect(Collectors.joining("/")));
            mm.put("SHOWTYPE", String.valueOf(a.get(0).get("SHOWTYPE")));
            if (StringUtils.isNotBlank(groupId)) {
                mm.put("TH_WIDTH", String.valueOf(a.get(0).get("TH_WIDTH")));
            }
            if (StringUtils.isNotBlank(groupId)) {
                mm.put("TH_ALIGN", String.valueOf(a.get(0).get("TH_ALIGN")));
            }
            return mm;
        }).collect(Collectors.toList());
        if ("0".equals(type)) {
            return tabulationData;
        }
        //排序
        if (StringUtils.isBlank(ordering)) {
                ordering = elasticsearchApiMapper.selectAppData(tenantCode + "_TABLEHEAD ", "CONTENT", "  " +
                        "type= '0' and menu_id= '" + menuId + "' and QZH = '" + qzh + "' ");
        }
        if (StringUtils.isNotBlank(ordering)) {
            ordering = ordering.replaceAll("ASC", "").replaceAll("DESC", "").replaceAll("NONE", "");
            String[] split = ordering.split(",");
            List<Map<String, String>> tabulationDataT = new ArrayList<>();
            for (String ss : split) {
                tabulationDataT.addAll(tabulationData.stream().filter(f -> f.get("FIELD_NAME").toLowerCase().
                        equals(ss.toLowerCase().trim())).collect(Collectors.toList()));
            }
            return tabulationDataT;
        }
        return tabulationData;
    }


    /**
     * 查询条件
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> queryApply(JSONObject json) {
        String categoryId = json.getString("categoryId"); //门类id
        String menuId = json.getString("menuId"); //菜单id
        String groupId = json.getString("groupId"); //菜单id
        if ("-1".equals(categoryId)) {
            return null;
        }
        //应用定义表名处理
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sql = new StringBuilder(" 1=1 ");
        //查询应用定义信息
        String queryData = elasticsearchApiMapper.selectAppData(tenantCode +
                Constants.TABLE_YQ_APP, " JIANQUERY ", " MENU_ID = '" + menuId + "' "
                + " and CATEGORY_ID = '" + categoryId + "' ");
        if (StringUtils.isNotBlank(queryData)) {
            sql.append(" and FIELD_NAME in  ('" + queryData.replace(",", "','") + "') ");
        } else {
            sql.append(" and IS_QUERY != 0 ");
        }
        sql.append(" and GROUP_ID = '" + groupId + "' and  type = 0  ");
        //查询元数据方案信息
        List<Map<String, Object>> tabulationList = elasticsearchApiMapper.selectTableData(tenantCode +
                Constants.BIG_TABLE_M_DATA_LIST, " FIELDTYPE,FIELD_NAME,FIELD_CAPTION,IS_QUERY,SHOWTYPE ", sql.toString());
        List<Map<String, Object>> tabulationData = tabulationList.stream().collect(Collectors.groupingBy(c -> c.get("FIELD_NAME"))).values().stream().map(a ->
        {
            Map<String, Object> mm = new HashMap<>();
            mm.put("FIELDTYPE", String.valueOf(a.get(0).get("FIELDTYPE")));
            mm.put("FIELD_NAME", String.valueOf(a.get(0).get("FIELD_NAME")));
            mm.put("FIELD_CAPTION", a.stream().map(dd -> String.valueOf(dd.get("FIELD_CAPTION"))).distinct().collect(Collectors.joining("/")));
            mm.put("IS_QUERY", String.valueOf(a.get(0).get("IS_QUERY")));
            mm.put("SHOWTYPE", Integer.parseInt(a.get(0).get("SHOWTYPE").toString()));
            return mm;
        }).collect(Collectors.toList());
        return tabulationData;
    }


    //拼接前端查询条件
    public String concatQueryCondition(QueryFile queryFile, String field) {
        StringBuilder queryCondition = new StringBuilder();
        //拼接前端查询条件
        if (queryFile.getQueryParameters() != null && queryFile.getQueryParameters().size() > 0) {
            queryFile.getQueryParameters().forEach(q -> {
                String[] queryValue = new String[2];    //查询值
                String queryType = q.getQueryType();      //查询类型
                String showType = q.getShowType();        //展示类型
                String fieldName = q.getColumn();
                if ("4".equals(queryType)) {    //区间查询会有2个值
                    queryValue[0] = q.getValue();        //根据查询项获取对应的查询值
                    queryValue[1] = q.getValueTwo();
                } else {
                    queryValue[0] = q.getValue();        //根据查询项获取对应的查询值
                }
                //logger.debug("queryColumns["+j+"] = "+queryColumns[j]+"--"+queryValue[0]);
                queryCondition.append(getQueryCriteriaByType(fieldName, showType, queryType, queryValue, field));
            });
        }
        return queryCondition.toString();
    }

    /**
     * <p>Title: getQueryCriteriaByType</p>
     * <p>Description: 根据传入的类型type 组合查询条件</p>
     *
     * @param column   列名
     * @param showType 查询类型
     *                 0	不参加查询	暂不考虑;
     *                 1	精确查询		= '匹配值';
     *                 2	模糊查询		like '%匹配值%';
     *                 3	左匹配查询	like '匹配值%';
     *                 4	区间查询		'匹配值1'<列<'匹配值2'	?是否包含=;
     *                 5	列表查询		不做处理;
     *                 6	单选对话框	不做处理;
     *                 7	多选对话框	不做处理;
     *                 8	多词检索		分词 以空格为标志;
     * @param values   查询值
     * @return
     */
    public String getQueryCriteriaByType(String column, String showType, String queryType, String[] values, String field) {
        String criteria = " ";
        Integer type = Integer.parseInt(queryType);
        switch (type) {
            case 0: //不参加查询	暂不考虑;
                criteria = " ";
                break;
            case 1: //精确查询	= '匹配值';
                criteria += " and " + column + " = '" + values[0] + "' ";
                break;
            case 2: //模糊查询	like '%匹配值%';
                criteria += " and " + column + " like '%" + values[0] + "%' ";
                break;
            case 3: //左匹配查询	like '匹配值%';
                criteria += " and " + column + " like '" + values[0] + "%' ";
                break;
            case 4: //区间查询	'匹配值1'<=列<='匹配值2'
                if (cn.yuanqiao.common.utils.StringUtils.isNotEmpty(values[0])) {
                    criteria += " and '" + values[0] + "' <= " + column;
                }
                if (cn.yuanqiao.common.utils.StringUtils.isNotEmpty(values[1])) {
                    criteria += " and " + column + " <= '" + values[1] + "' ";
                }
                break;
            case 5: //列表查询	不做处理;
                criteria = " ";
                break;
            case 6: //单选对话框	不做处理;
                criteria = " ";
                break;
            case 7: //多选对话框	不做处理;
                criteria = " ";
                break;
            case 8: //多词检索	分词 以空格为标志;	多词检索中 如果有查询列里的值存在空格 怎么处理 (查询时使用""将带空格需要整体查询的值标记 , 例如:"A B")
                criteria = " and CONCAT( " + field + " ) like '%" + values[0] + "%' ";
                break;
            default:
                break;
        }
        return criteria;
    }

    /**
     * 查询门类信息
     *
     * @param type
     * @param menuId
     * @return
     */
    public List<Map<String, Object>> queryCategoryIds(String type, String menuId,String qzh) {
        List<SysRole> roles = SecurityUtils.getLoginUser().getSysUser().getRoles();
        if (roles == null && roles.size() <= 0) {
            return null;
        }
        String collect = roles.stream().map(m -> String.valueOf(m.getRoleId())).collect(Collectors.joining(","));
        String tenantCode = SecurityUtils.getTenantCode();
        StringBuilder sql = new StringBuilder("");
        sql.append(" select c.GROUP_ID,c.ID,c.NAME,c.TYPE,c.ITEM_TABLE_NAME,c.FOLDER_TABLE_NAME,c.FILE_TABLE_NAME from " + tenantCode + Constants.BIG_TABLE_NAME_TREESROLE);
        sql.append(" tr LEFT JOIN " + tenantCode + Constants.BIG_TABLE_NAME_TREES);
        sql.append(" t ON t.ID = tr.TREE_ID ");
        sql.append(" LEFT JOIN " + tenantCode + Constants.BIG_TABLE_NAME);
        sql.append(" c ON t.CATEGORY_ID = c.ID  where c.IS_DEL = 0 and c.GROUP_ID is not null and t.TYPE='a' ");
        if (!SecurityUtils.isDagly()) {
            sql.append(" and tr.ROLE_ID IN (" + collect + ")");
            sql.append(" and tr.MENU_ID = '" + menuId + "' ");
        }
        if (StringUtils.isNotBlank(type)) {
            sql.append(" and c.TYPE = " + type);
        }
        if (StringUtils.isNotBlank(qzh)&& !"-1".equals(qzh)) {
            sql.append(" and c.fonds_code = '" + qzh+"' ");
        }
        //查询门类信息
        List<Map<String, Object>> categoryList = elasticsearchApiMapper.selectLeftJoinTableData(" GROUP_ID, ID,NAME,TYPE,ITEM_TABLE_NAME,FOLDER_TABLE_NAME,FILE_TABLE_NAME ", "", sql.toString());
        List<Map<String, Object>> categoryListd = new ArrayList<>();
        if (categoryList != null) {
            categoryListd = categoryList
                    .stream().collect(
                            Collectors.collectingAndThen(
                                    Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(m -> String.valueOf(m.get("ID"))))), ArrayList::new)
                    );
        }
        return categoryListd;
    }

}
